package com.edu.admin.service;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.edu.admin.common.BaseService;
import com.edu.admin.entity.SysClasses;
import com.edu.admin.entity.SysGrade;
import com.edu.admin.enums.ExceptionEnum;
import com.edu.admin.exception.SysException;
import com.edu.admin.mapper.ClassesMapper;
import com.edu.admin.utils.DateUtils;
import com.edu.admin.utils.ExcelUtils;
import com.edu.admin.utils.UploadUtil;
import com.edu.admin.vo.ClassesSubjectVo;
import com.edu.admin.vo.ClassesTeacherVo;
import com.edu.admin.vo.ClassesVo;
import com.edu.admin.vo.GradeVo;
import com.edu.admin.vo.SchoolPhaseVo;
import com.edu.admin.vo.SchoolVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

/**
 * 班级服务
 * 
 * @author Wangjiong
 * 
 */
@Transactional
@Service
public class ClassesService extends BaseService<ClassesMapper, SysClasses> {
	
	@Autowired
	GradeService gradeService;
	@Autowired
	SchoolService schoolService;
	@Autowired
	UserService userService;
	@Autowired
	SchoolPhaseService schoolPhaseService;
	
	@Value("${error.logfile:c:/}")
    private String logfile;
	
	/**
	 * 获取班级信息
	 * 
	 * @param classesId
	 * 
	 * @return ClassesVo
	 * @throws InvocationTargetException 
	 * @throws IllegalAccessException 
	 */
	public ClassesVo getClassesById(Long classesId) throws IllegalAccessException, InvocationTargetException{
		
		ClassesVo classesVo = this.mapper.getClassesByClassesId(classesId);
		
		return classesVo;
	}
	
	/**
	 * 获取班级信息
	 * 
	 * @param schoolId
	 * @param phaseId
	 * @param gradeId
	 * @param classesNo
	 * 
	 * @return ClassesVo
	 */
	public ClassesVo getClassesByNo(Long schoolId, Long phaseId,Long gradeId,
									Integer classesNo){
		
		ClassesVo classes = null;
		
		if (schoolId!=null && phaseId!=null && gradeId!=null && classesNo!=null 
			&& schoolId >0 && phaseId >0 && gradeId >0 && classesNo >0)	{
			
			classes = this.mapper.getClassesByNo(schoolId, phaseId, gradeId, classesNo);
		}

		return classes;
	}
	
	/**
	 * 通过班级名称获取班级信息
	 * 
	 * @param schoolId
	 * @param classesName
	 * 
	 * @return ClassesVo
	 */
	public ClassesVo getClassesByName(Long schoolId, String classesName){
		
		ClassesVo classes = null;
		
		if (schoolId!=null && classesName!=null && schoolId >0)	{
			
			classes = this.mapper.getClassesByName(schoolId, classesName);
		}

		return classes;
	}
	
	/**
	 * 获取班级列表
	 * 
	 * @param schoolId
	 * @param phaseId
	 * @param gradeId
	 * 
	 * @return List<ClassesVo>
	 */
	public List<ClassesVo> getClassesList(Long schoolId, Long phaseId,Long gradeId) {
				
		List<ClassesVo> classesList = this.mapper.getClassesList(schoolId, phaseId, gradeId);
	
		return classesList;
	}
	
	/**
	 * 获取所有班级列表（包括停用班级）
	 * 
	 * @param schoolId
	 * @param phaseId
	 * @param gradeId
	 * 
	 * @return List<ClassesVo>
	 */
	public List<ClassesVo> getAllClassesList(Long schoolId,Long phaseId,Long gradeId, Integer isGraduated){
		
		List<ClassesVo> classesList = this.mapper.getAllClassesList(schoolId,phaseId,gradeId,isGraduated);

		return classesList;
	}
	
	/**
	 * 获取所有班级列表（包括停用班级）（分页）
	 * 
	 * @param pageNum
	 * @param pageSize
	 * @param schoolId
	 * @param phaseId
	 * @param gradeId
	 * 
	 * @return PageInfo<ClassesVo>
	 */
	public PageInfo<ClassesVo> getAllClassesListPage(Integer pageNum, Integer pageSize,
													Long schoolId, Long phaseId,
													Long gradeId, Integer isGraduated){
		if (pageNum == null) {
			pageNum = 1;
		}
		if (pageSize == null) {
			pageSize = 10;
		}
		PageHelper.startPage(pageNum, pageSize);
		
		List<ClassesVo> classesList = this.mapper.getAllClassesList(schoolId,phaseId,gradeId,isGraduated);
			
		PageInfo<ClassesVo> pageInfo = new PageInfo<ClassesVo>(classesList);

		return pageInfo;
	}
	
	/**
     * 班级重复性检查
     * 
     * @param SysClasses classes
     * 
     * @return List<ClassesVo>
     * @throws Exception
     */
    public List<ClassesVo> CheckClasses(SysClasses classes) throws Exception {
    	
    	return this.mapper.findClassesByClassesNo(classes.getClassesId(), 
									    			classes.getClassesNo(),
									    			classes.getSchoolId(),
									    			classes.getPhaseId(),
									    			classes.getGradeId());
  
    }
    
	/**
	 * 班级保存
	 * 
	 * @param SysClasses
	 * 
	 * @return Map<String, Object>
	 * @throws Exception 
	 */
	public Map<String, Object> saveClasses(SysClasses classes) throws Exception {
		
		Map<String, Object> result = new HashMap<>();
		
		List<ClassesVo> classesList = CheckClasses(classes);
		
		if (classesList!=null && classesList.size()>0)
		{
			throw new SysException(ExceptionEnum.CLASSESNAMEREPEAT);
		}
		
		Long classesId = classes.getClassesId();

		if (classesId == null) {
			
			Long schoolId = classes.getSchoolId();
			Long phaseId = classes.getPhaseId();
			Long gradeId = classes.getGradeId();
			Integer classesNo = classes.getClassesNo();
			String classesName = classes.getClassesName();
			
			
			if (schoolId== null  || phaseId== null || gradeId== null  || classesNo== null || classesName== null
				|| schoolId <1 || phaseId <1 || gradeId <1 || classesNo <1 || classesName.isEmpty())
			{
				throw new SysException(ExceptionEnum.VALIDERROR);
			}
			
			ClassesVo oldClasses = this.mapper.getClassesByNo(schoolId, phaseId, gradeId, classesNo);
			
			if (oldClasses!=null)
			{
				throw new SysException(ExceptionEnum.CLASSESREPEAT);
			}
			
			classes.setUseType(0);
			
			insert(classes);
			
			classesId = classes.getClassesId();

		} else {
			
			updateByPrimaryKeySelective(classes);

		}
		
		result.put("classesId", classesId);

		return result;
		
	}
	
	/**
	 * 删除班级
	 * 
	 * @param classesId
	 * 
	 * @return int
	 * 
	 */
	public int deleteClasses(Long classesId) {
		
		if (classesId != null) {
			
			Integer studentCount = userService.getStudentCount(null, null, classesId);
			
			if (studentCount>0)
			{
				throw new SysException(ExceptionEnum.CLASSESNOEMPTY);
			}
			
			return this.deleteByPrimaryKey(classesId);

		}
		
		return 0;	

	}
	
	/**
	 * 保存班主任
	 * 
	 * @param classesId
	 * @param teacherId
	 * 
	 * @return int
	 * @throws Exception 
	 */
	public int saveClassesTeacher(Long classesId,Long teacherId) throws Exception {
		
		SysClasses classes = new SysClasses();
		
		classes.setClassesId(classesId);
		classes.setTeacherId(teacherId);
		
		return updateByPrimaryKeySelective(classes);


		
	}
	
	/**
	 * 获取班级学科列表
	 * 
	 * @param phaseId
	 * @param classesId
	 * 
	 * @return List<ClassesSubjectVo>
	 */
	public List<ClassesSubjectVo> getClassesSubjectList(Long phaseId,Long classesId) {
				
		List<ClassesSubjectVo> classesSubjectList = this.mapper.getClassesSubjectList(phaseId,classesId);
	
		return classesSubjectList;
	}
	
	
	/**
	 * 班级学科教师可选择列表
	 * 
	 * @param schoolId
	 * @param phaseId
	 * @param classesId
	 * @param subjectId
	 * @param userName
	 * @param selectids
	 * 
	 * @return List<ClassesTeacherVo>
	 */
	public List<ClassesTeacherVo> getUnselectedTeacherList(Long schoolId,
															Long phaseId,
															Long classesId,
															Long subjectId,
															String userName,
															String selectids) {
				
		List<ClassesTeacherVo> classesTeacherList = this.mapper.getUnselectedTeacherList(schoolId,phaseId,classesId,subjectId,userName,selectids);
		
		return classesTeacherList;
	}
	
	
	/**
	 * 班级学科已任教教师列表
	 * 
	 * @param schoolId
	 * @param phaseId
	 * @param classesId
	 * @param subjectId
	 * 
	 * @return List<ClassesTeacherVo>
	 */
	public List<ClassesTeacherVo> getSelectedTeacherList(Long schoolId,
															Long phaseId,
															Long classesId,
															Long subjectId) {
				
		List<ClassesTeacherVo> classesTeacherList = this.mapper.getSelectedTeacherList(schoolId,phaseId,classesId,subjectId);
	
		return classesTeacherList;
	}
	
	
	/**
	 * 导入班级
	 * 
	 * @param file
	 * @param schoolId
	 * @param request
	 * 
	 * @return Map<String, Object>
	 * 
	 * @throws Exception
	 */
	public Map<String, Object> importClasses(MultipartFile file, 
									Long schoolId, 
									HttpServletRequest request) throws Exception {

		int iRow = 0;
		String orderNumField = "序号（必填）";  
		String phaseNameField = "学段（必填）";
		String gradeNameField = "年级（必填）";
		String classesNoField = "班级编号（必填）";
		String enterYearField = "入学年份（必填）";
		String personalityNameField = "个性班名";
		Integer orderNum; 
		String phaseName;
		String gradeName;
		Integer classesNo;
		String enterYear;
		String graduateYear ;
		String personalityName;
		Long phaseId;
		Long gradeId;
		Integer duration;
		Integer yearNum;

		
		Map<String, Object> result = new HashMap<>();
		
		List<Map<String, Object>> errorList = new ArrayList<>();

		UploadUtil uploadUtil = new UploadUtil();

		String filePath = uploadUtil.upload(file, schoolId ,request);
		if (filePath == null) {
			throw new SysException(ExceptionEnum.UPLOADERROR);
		}

		String[] attrs = { "orderNum", "phaseName", "gradeName", "classesNo", "enterYear","personalityName" };
		List<Map<String, Object>> classesList = ExcelUtils.importExcel(filePath, 0, 0, attrs);
		

		for (Map<String, Object> classesMap : classesList) {
			
			Map<String, Object> errorInfo = new HashMap<>();
			
			try {
				if (iRow == 0) {
					
					StringBuilder errorBuilder = new StringBuilder();
					
					orderNumField = MapUtils.getString(classesMap, "orderNum");
					phaseNameField = MapUtils.getString(classesMap, "phaseName");
					gradeNameField = MapUtils.getString(classesMap, "gradeName");
					classesNoField = MapUtils.getString(classesMap, "classesNo");
					enterYearField = MapUtils.getString(classesMap, "enterYear");
					personalityNameField = MapUtils.getString(classesMap, "personalityName");
						
					if (orderNumField.indexOf("序号")<0)
					{
						errorBuilder.append("第一列必须是序号列").append(",");
					}
					
					if (phaseNameField.indexOf("学段")<0) {
						errorBuilder.append("第二列必须是学段列").append(",");
					}
					
					if (gradeNameField.indexOf("年级")<0) {
						errorBuilder.append("第三列必须是年级列").append(",");
					}
					
					if (classesNoField.indexOf("班级编号")<0) {
						errorBuilder.append("第四列必须是班级编号列").append(",");
					}
					
					if (enterYearField.indexOf("入学年份")<0) {
						errorBuilder.append("第五列必须是入学年份列").append(",");
					}
					
					if (errorBuilder.length()>0)
					{
						errorInfo.put("orderNum", 0);
						errorInfo.put("info", errorBuilder.substring(0, errorBuilder.length()-2));
						errorList.add(errorInfo);
						
						result.put("statusinfo", "error");
						result.put("errordata", errorList);
						
						return result;
					}
					

				} 
				else
				{
					
					orderNum = MapUtils.getInteger(classesMap, orderNumField);//序号
					errorInfo.put("orderNum", orderNum);
					
					if (orderNum==null)
					{
						continue;
					}
									
					phaseName = MapUtils.getString(classesMap, phaseNameField);// 学段
					gradeName = MapUtils.getString(classesMap, gradeNameField);// 年级
					classesNo = MapUtils.getInteger(classesMap, classesNoField);// 班级编号
					enterYear = MapUtils.getString(classesMap, enterYearField);// 入学年份
					if (personalityNameField!=null && !personalityNameField.isEmpty()){
						personalityName = MapUtils.getString(classesMap, personalityNameField);// 个性班名
					}
					else
					{
						personalityName = "";
					}
					
					if (phaseName==null || phaseName.trim().isEmpty()) 
					{
						errorInfo.put("info", "学段为空");
						errorList.add(errorInfo);
						continue;
					}
					
					List<SchoolPhaseVo> phaseList = schoolPhaseService.getSchoolPhaseBySchoolIdAndPhaseName(schoolId, phaseName);
	                if(phaseList == null || phaseList.size()==0){
	                	errorInfo.put("info","学段不存在");
	                	errorList.add(errorInfo);
	                    continue;
	                }
	                else
	                {
	                	phaseId = phaseList.get(0).getPhaseId();
	                	duration = phaseList.get(0).getDuration();
	                }
						
					if (gradeName==null || gradeName.trim().isEmpty()) 
					{
						errorInfo.put("info", "年级为空");
						errorList.add(errorInfo);
	                    continue;
	                }
					
					SysGrade grade = new SysGrade();
					grade.setPhaseId(phaseId);
					grade.setGradeName(gradeName);
					List<GradeVo> gradeList = gradeService.CheckGrade(grade);
	                if(gradeList == null || gradeList.size()==0){
	                	errorInfo.put("info","年级不存在");
	                	errorList.add(errorInfo);
	                    continue;
	                }
	                else
	                {
	                	gradeId = gradeList.get(0).getGradeId();
	                	yearNum = gradeList.get(0).getYearNum();
	                }
	                
					if (classesNo==null) 
					{
						errorInfo.put("info", "班级编号为空");
						errorList.add(errorInfo);
						continue;
					}
					
					ClassesVo oldClasses = getClassesByNo(schoolId,phaseId,gradeId,classesNo);
					
					if (oldClasses!=null) 
					{
						errorInfo.put("info", "班级已存在");
						errorList.add(errorInfo);
						continue;
					}
							
					if (enterYear==null || enterYear.trim().isEmpty()) 
					{
						errorInfo.put("info", "入学年份");
						errorList.add(errorInfo);
						continue;
					}
			
					SysClasses newClasses = new SysClasses();
					
					String classesName = gradeName + classesNo +"班";
					
					newClasses.setSchoolId(schoolId);
					newClasses.setClassesName(classesName);
					newClasses.setClassesNo(classesNo);
					newClasses.setGradeId(gradeId);
					newClasses.setPhaseId(phaseId);
					newClasses.setPersonalityName(personalityName);
					
					enterYear = DateUtils.changePattern(enterYear,"yyyy","yyyy");
					newClasses.setEnterYear(enterYear);
					
	                graduateYear = DateUtils.getAfterYear(enterYear, duration);
	           
	                int nowYear = DateUtils.getNowYear();
	                int nowMonth = DateUtils.getNowMonth();
	                String cYear = "";
	                if(nowMonth < 8){
	                    cYear = DateUtils.getAfterYear(enterYear, yearNum);
	                }else{
	                    cYear = DateUtils.getAfterYear(enterYear, yearNum - 1);
	                }
	                if (Integer.valueOf(cYear) != nowYear){
	                	errorInfo.put("info","入学年与年级不匹配");
	                	errorList.add(errorInfo);
	                    continue;
	                }
	                
	                newClasses.setGraduateYear(graduateYear);
	                newClasses.setIsGraduated(0);
										
					saveClasses(newClasses);
										
				}

			} catch (Exception e) {
				e.printStackTrace();
				errorInfo.put("info", "班级保存失败");
				errorList.add(errorInfo);
			}

			iRow++;
		}

		// 统计学校班级数据
		schoolService.updateSchoolClassesNum(schoolId);

		if (errorList.size() > 0) {
			result.put("statusinfo", "error");
			result.put("errordata", errorList);
		} else {
			result.put("statusinfo", "success");
		}

		return result;
	}
	
	
	/**
	 * 删除班级
	 * 
	 * @param classesId
	 * 
	 * @return int
	 * @throws Exception 
	 * 
	 */
	public void schoolUpgrading(Long schoolId) throws Exception {
		
		StringBuilder upgradingInfo = new StringBuilder();
		
		if (DateUtils.getNowMonth()<8)
		{
			throw new SysException(ExceptionEnum.SCHOOLUPGRADINGMONTHERROR);
		}
		
		List<SysClasses> classesList = this.mapper.getSysClassesList(schoolId);
		
		BufferedWriter out = null;     
        try {     
	        File txtFile=new File(logfile);
	        if(!txtFile.exists()){
	        	txtFile.createNewFile();    
	        }
	        
	        out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(logfile, true)));   
	        out.write(DateUtils.getNowTime()+"\r\n"); 
			
			for (SysClasses classes : classesList)
			{
				String classesName;
				String enterYear = classes.getEnterYear();
				String graduateYear = classes.getGraduateYear();
				Integer yearNum = classes.getYearNum();
	
				int nowYear = DateUtils.getNowYear();
				
				upgradingInfo.delete(0, upgradingInfo.length() );
				
				upgradingInfo.append("classesId:").append(classes.getClassesId()).append(" , ");
		        
		        if (Integer.valueOf(graduateYear).intValue()<= nowYear)
		        {
		        	classes.setIsGraduated(1);
		        	classesName = graduateYear + "届" + classes.getClassesNo() + "班";
		        	classes.setClassesName(classesName);
		        	saveClasses(classes);
		        	upgradingInfo.append("info:").append("升班成功！\r\n");
		            out.write(upgradingInfo.toString());  
		        }
		        else
		        {
		        
			        String cYear = "";
			 
			        cYear = DateUtils.getAfterYear(enterYear, yearNum - 1);
			       
			        if (Integer.valueOf(cYear).intValue() != nowYear){
			        	int yearindex = nowYear - Integer.valueOf(enterYear) + 1;
			        	if (yearindex <0) 
			        	{
			        		upgradingInfo.append("info:").append("升班失败！\r\n");
			                out.write(upgradingInfo.toString());  
			        		continue;
			        	}
			        	GradeVo grade = gradeService.getGradeByPhaseIdAndYearNum(classes.getPhaseId(), yearindex);
			        	if (grade == null) 
			        	{
			        		upgradingInfo.append("info:").append("升班失败！\r\n");
			                out.write(upgradingInfo.toString());  
			        		continue;
			        	}
			        	classes.setGradeId(grade.getGradeId());
			        	classesName = grade.getGradeName() +  classes.getClassesNo() + "班";
			        	classes.setClassesName(classesName);
			        	saveClasses(classes);
			        	upgradingInfo.append("info:").append("升班成功！\r\n");
			            out.write(upgradingInfo.toString());  
			        }
			        else
			        {
			        	upgradingInfo.append("info:").append("无需升班！\r\n");
			            out.write(upgradingInfo.toString());  
			        }
		        }
			}
			
			List<SchoolVo> schoolList = schoolService.getSchoolList(null, null, null, null);
			for (SchoolVo school :schoolList)
			{
				// 统计学校班级数据
				schoolService.updateSchoolClassesNum(school.getSchoolId());
				// 统计学校学生数据
				schoolService.updateSchoolStudentNumBySchoolId(school.getSchoolId());
			}
		

        } catch (Exception e) {     
           e.printStackTrace();     
        } finally {     
           try {     
               if(out != null){  
                   out.close();     
               }  
           } catch (IOException e) {     
               e.printStackTrace();     
           }     
       }
        
	}
	


}
